Thursday, July 7, 2016
Python -- Pandas -- Add a new level to the column in DataFrame
Here is the situation, we have a data frame df
X Y Z
0 0.738596 0.852906 0.333422
1 0.820456 0.014704 0.233935
2 0.118291 0.714536 0.176275
3 0.032417 0.819386 0.949590
4 0.739559 0.923865 0.791574
And for some reason, we want to add a new level to the columns. Unlike adding new level to index, it seems that there is no available function in Pandas to handle this problem.
We can of course do it "manually", something like this:
df.columns = pd.MultiIndex.from_arrays(np.vstack((np.asarray(['test'] * df.shape[1]), df.columns.tolist())))
A more general function is
def add_new_level(index, new_level):
arrays = np.asarray(index.get_values().tolist()).T
new_arrays = np.vstack((new_level, arrays))
return pd.MultiIndex.from_arrays(new_arrays)
(not sure if this is the simplest one, have some doubts)
and the data frame becomes:
test
X Y Z
0 0.738596 0.852906 0.333422
1 0.820456 0.014704 0.233935
2 0.118291 0.714536 0.176275
3 0.032417 0.819386 0.949590
4 0.739559 0.923865 0.791574
or we can play some trick like this one:
df = pd.concat([df], axis=1, keys=['test'])
Sunday, June 26, 2016
Programming Problems about Stocks
LeetCod 122: Best Time to Buy and Sell Stock II
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.empty()) return 0;
int max_output = 0;
int max_profit_normal = 0;
int max_profit_sell_at_i = prices.back();
for (int i = prices.size()-2; i >= 0; --i) {
max_profit_normal = max(max_profit_sell_at_i - prices[i], max_profit_normal);
max_profit_sell_at_i = max_profit_normal + prices[i];
}
return max_profit_normal;
}
};
LeetCode 123: Best Time to Buy and Sell Stock III
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most two transactions.
Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
class Solution {
public:
int maxProfit(vector<int>& prices) {
vector<int> min_prices(prices.size(), 0);
int min_val = numeric_limits<int>::max();
for (int i = 0; i < prices.size(); ++i) {
min_val = min(min_val, prices[i]);
min_prices[i] = min_val;
}
vector<int> max_prices(prices.size(), 0);
int max_val = numeric_limits<int>::min();
for (int j = prices.size()-1; j >=0; --j) {
max_val = max(max_val, prices[j]);
max_prices[j] = max_val;
}
vector<int> max_profit(prices.size(), 0);
int max_profit_so_far = 0;
for (int i = 0; i < prices.size(); ++i) {
max_profit_so_far = max(max_profit_so_far, prices[i] - min_prices[i]);
max_profit[i] = max_profit_so_far;
}
vector<int> max_profit_from_right(prices.size(), 0);
int max_profit_so_far_from_right = 0;
for (int i = prices.size()-1; i >= 0; --i) {
max_profit_so_far_from_right = max(
max_profit_so_far_from_right, max_prices[i] - prices[i]);
max_profit_from_right[i] = max_profit_so_far_from_right;
}
int output = 0;
for (int i = 0; i < prices.size(); ++i) {
output = max(output, max_profit[i] + max_profit_from_right[i]);
}
return output;
}
};
LeetCode 309: Best Time to Buy and Sell Stock with Cooldown
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times) with the following restrictions:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
After you sell your stock, you cannot buy stock on next day. (ie, cooldown 1 day)
class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.empty()) return 0;
int n = prices.size();
vector<int> maxProfit(n, 0);
for (int i = n-2; i >= 0; --i) {
int maxProfit_if_buy_at_i = numeric_limits<int>::min();
for (int j = i+1; j < n; ++j) {
maxProfit_if_buy_at_i = max(maxProfit_if_buy_at_i,
prices[j] - prices[i] + (j + 2 < n ? maxProfit[j + 2] : 0));
}
maxProfit[i] = max(maxProfit[i+1], maxProfit_if_buy_at_i);
}
return maxProfit[0];
}
};
LeetCode 188: Best Time to Buy and Sell Stock IV
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most k transactions.
Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
if (prices.empty()) return 0;
int ndays = prices.size();
if (k >= prices.size()/2) {
int res = 0;
for (int i = 1; i < prices.size(); ++i)
res += max(prices[i] - prices[i-1], 0);
return res;
}
vector<int> B(ndays,0);
vector<int> S(ndays,0);
int max_val_B;
int max_val_S;
for (int kk = 0; kk < k; ++kk){
//cout << "===== " << kk << " =====" << endl;
max_val_B = numeric_limits<int>::min();
max_val_S = numeric_limits<int>::min();
for (int i = 0; i < ndays; ++i) {
max_val_B = max(max_val_B, S[i]-prices[i]);
max_val_S = max(max_val_S, max_val_B + prices[i]);
B[i] = max_val_B;
S[i] = max_val_S;
}
}
return S.back();
}
};
Tuesday, June 21, 2016
Late Binding Behavior in Python
One interesting mistake mentioned in https://www.toptal.com/python/top-10-mistakes-that-python-programmers-make is the late binding behavior in Python.
Here is the problem, suppose we want to have the following function:
def create_multiplier():
return [lambda x: x * i for i in range(5)]
for func in create_multipler():
print(func(2))
We expect the code to print 0,2,4,6,8 while the actual output is 8,8,8,8,8. As explained in the post
"This happens due to Python’s late binding behavior which says that the values of variables used in closures are looked up at the time the inner function is called. So in the above code, whenever any of the returned functions are called, the value of i is looked up in the surrounding scope at the time it is called(and by then, the loop has completed, so i has already been assigned its final value of 4)."
And the author propose a hack solution to the problem:
>>> def create_multipliers():
... return [lambda x, i=i : i * x for i in range(5)]
...
>>> for multiplier in create_multipliers():
... print multiplier(2)
...
0
2
4
6
8
There is another solution to handle this problem, we define the create_multipliers as:
>>> def create_multipliers(): ... return (lambda x: x * i for i in range(5))
Instead of returning a list we return a generator. In this case, when the function is called, the i in range(5) only moves one step ahead.
>>> def create_multipliers():
... return (lambda x : x * i for i in range(5))
>>> for func in create_multipliers():
... print(func(2))
0
2
4
6
8
Sunday, June 19, 2016
Implementation of Singleton in Python
This is a simple implementation of the singleton in Python
class Singleton(type):
def __new__(cls, name, bases, namespace):
namespace['_instance'] = None
return super(Singleton, cls).__new__(cls, name, bases, namespace)
class SingletonBase(metaclass=Singleton):
def __new__(cls, *args, **kwargs):
if cls._instance is None:
print("Create new instance for class {}".format(cls.__name__))
instanceof = super(SingletonBase, cls).__new__(cls)
cls._instance = instanceof
return instanceof
else:
print("The class {} has been instantiated".format(cls.__name__))
return cls._instance
class MyClass(SingletonBase):
def __init__(self,val):
self._val = val
if __name__ == '__main__':
x = MyClass(10)
y = MyClass(20)
print("pointer of x: {}".format(x))
print("pointer of y: {}".format(y))
assert x is y
print("x._val: {}".format(x._val))
print("y._val: {}".format(y._val))
Tuesday, June 14, 2016
Implementation of immutable class in Python 3.5
# In this script, we will implement an Immutable class.
# The implementation is developed with Python 3. In order to run the code with Python2.7, we need to change the
# __setattr__ function in ImmutableBase to _setattribute__ function .
class ImmutableMeta(type):
def __new__(cls, name, bases, namespace):
namespace['_instances'] = []
return super(ImmutableMeta, cls).__new__(cls, name, bases, namespace)
class ImmutableBase(metaclass=ImmutableMeta):
def __setattr__(self, name, val):
if self in self._instances:
raise Exception("The class is immutable.")
self.__dict__[name] = val
def __getattribute__(self, item):
if item == '__dict__' and self in self._instances:
raise Exception("Not allowed to access __dict__.")
return super(ImmutableBase, self).__getattribute__(item)
def __init__(self):
self._instances.append(self)
class MyImmutableClass(ImmutableBase):
def __init__(self, x):
self.x = x
super(MyImmutableClass, self).__init__()
if __name__ == '__main__':
instanceof = MyImmutableClass(10)
instanceof.x = 200
Friday, May 13, 2016
一道关于飞机加油的问题
问题:
每个飞机只有一个邮箱,飞机之间可以互相加油并且一箱油可供一架飞机绕地球飞半圈, 问为使至少一架飞机绕地球一圈飞回起飞的地方,至少需要出动几架飞机? (所有飞机从同一机场起飞,而且必须安全返回机场,不允许中途降落,中间没有飞机场)
不知道这道题的正确解是多少,这里给出4架安排的方法。
为方便起见先给地球标上坐标。从起点开始自西向东分别标记为 0->1->2->3->4->5->0
plane A: from 0 to 1, oil = 1/2 - 1/6 = 2/6 when x = 1
plane B: from 0 to 1, oil=2/6 when x = 1
1/6 oil from B to A, now, plane A oil = 1/2, plane B oil = 1/6
plane B back to start point
plane A fly to x = 4
meanwhile
plane B from 0 to 5, oil = 2/6 at x = 5
plane C from 0 to 5, oil = 2/6 at x = 5
1/6 oil from B to C, now plane C has 3/6 oil and plane B has 1/6 oil
plane B back to start point
plane C from 5 to 4 with 2/6 oil at x = 4
at this point, plane C meets plane A
1/6 from C to A, now both A and C has 1/6 oil
meanwhile,
plane B and plane D starts from 0 and fly to x = 5
at x = 5, both B and D has 2/6 oil
also at x = 5, B and D meet A and C
B and D give 1/6 to A and C
and all of them can fly back to the start point
===================
I have no idea if we can do this with only three planes. It seems that the plane D is not fully used...
Longest Palindrome Substring O(n) Algorithm
Here is a very detailed explanation of the O(n) algorithm: https://www.felix021.com/blog/page.php?pageid=6
The key ideas are :
- We look for the center of the palindrom
- when scan the string we want to use the previous calculation
- palindrome is symmetric and we want to take advantage of this symmetric structure
This algorithm is a combination of Dynamic Program and Pruning.
Here is the implementation:
int longestPalindromeSubstring(string inStr) { // insert "space" between charaters in the orignal string. // this is a very useful pre-processing; it unifies the odd-length and even-length palindrom substring // It is obvious that we should use a character that does not appear in the original string. string s; for (int i = 0; i < inStr.size(); ++i) { s = s + '#'; s = s + inStr[i]; } s = s + '#'; vector<int> P(s.size(), 0); // Here is the definition of the op_center and op_length: // op_center + op_length is the right-most boundary of the known palindrome substring. int op_center = -1; int op_length = 0; int record = numeric_limits<int>::min(); // now, we scan the string and update op_center and op_length as well as the maximum lenght // of the palindrome substring. for (int i = 0; i < s.size(); ++i) { int curr_length = 0; if (i <= op_center + op_length) { // when current position is covered by a known palindrome substring int j = 2 * op_center - i; // here we take advantage of the symmetric structure curr_length = P[j]; } // perform the two direction search while (i + curr_length < s.size() && i - curr_length >= 0 && s[i+curr_length] == s[i-curr_length]) { ++curr_length; } P[i] = --curr_length; // update the record record = max(record, curr_length); if (i + curr_length > op_center + op_length) { op_center = i; op_length = curr_length; } } return record; }
Subscribe to:
Posts (Atom)