Вы можете использовать списки со сглаживанием для новых DataFrame
и затем DataFrame.merge
вместе с исходными данными:
data1 = pd.DataFrame({'Event Start':['03/28/2018','04/02/2018'],
'Event End':['04/03/2018','04/05/2018'],
'Team 1':['AAB','AAC'],
'Team 2':['BBB','ABC'],
'Total Spot':[160, 350]})
c = ['Event Start','Event End']
data1[c] = data1[c].apply(pd.to_datetime)
data1['Daily']=(data1['Total Spot']/((data1['Event End']-data1['Event Start']).dt.days)+1)
print (data1)
Event Start Event End Team 1 Team 2 Total Spot Daily
0 2018-03-28 2018-04-03 AAB BBB 160 27.666667
1 2018-04-02 2018-04-05 AAC ABC 350 117.666667
L = [(i, x) for i, s, e in zip(data1.index, data1['Event Start'], data1['Event End'])
for x in pd.date_range(s, e)]
df = (pd.DataFrame(L, columns=['idx','Day'])
.merge(data1.drop(c + ['Total Spot'], axis=1), left_on='idx', right_index=True)
.drop('idx', axis=1))
print (df)
Day Team 1 Team 2 Daily
0 2018-03-28 AAB BBB 27.666667
1 2018-03-29 AAB BBB 27.666667
2 2018-03-30 AAB BBB 27.666667
3 2018-03-31 AAB BBB 27.666667
4 2018-04-01 AAB BBB 27.666667
5 2018-04-02 AAB BBB 27.666667
6 2018-04-03 AAB BBB 27.666667
7 2018-04-02 AAC ABC 117.666667
8 2018-04-03 AAC ABC 117.666667
9 2018-04-04 AAC ABC 117.666667
10 2018-04-05 AAC ABC 117.666667
Другое подобное решение:
zipped = zip(data1['Team 1'], data1['Team 2'],
data1['Daily'], data1['Event Start'], data1['Event End'])
L = [(x, t1, t2, d) for t1, t2, d, s, e in zipped for x in pd.date_range(s, e)]
print (L)
df = pd.DataFrame(L, columns=['Day', 'Team 1','Team 2','Daily'])
print (df)
Day Team 1 Team 2 Daily
0 2018-03-28 AAB BBB 27.666667
1 2018-03-29 AAB BBB 27.666667
2 2018-03-30 AAB BBB 27.666667
3 2018-03-31 AAB BBB 27.666667
4 2018-04-01 AAB BBB 27.666667
5 2018-04-02 AAB BBB 27.666667
6 2018-04-03 AAB BBB 27.666667
7 2018-04-02 AAC ABC 117.666667
8 2018-04-03 AAC ABC 117.666667
9 2018-04-04 AAC ABC 117.666667
10 2018-04-05 AAC ABC 117.666667
Hum... just program it yourself using String.chatAt(int), it's pretty easy...
Iterate through all char in the string using a position index, then compare it using the fact that ASCII characters 0 to 9, a to z and A to Z use consecutive codes, so you only need to check that character x numerically verifies one of the conditions:
Here is a basic code sample (using CharSequence, which lets you pass a String but also a StringBuilder as arg):
public boolean isValidChar(CharSequence seq) {
int len = seq.length();
for(int i=0;i<len;i++) {
char c = seq.charAt(i);
// Test for all positive cases
if('0'<=c && c<='9') continue;
if('a'<=c && c<='z') continue;
if('A'<=c && c<='Z') continue;
if(c==' ') continue;
if(c=='-') continue;
// ... insert more positive character tests here
// If we get here, we had an invalid char, fail right away
return false;
}
// All seen chars were valid, succeed
return true;
}
You could use:
StringUtils.isAlphanumericSpace(string.replace('-', ' '));
Just iterate through the string, using the character-class methods in java.lang.Character to test whether each character is acceptable or not. Which is presumably all that the StringUtils methods do, and regular expressions are just a way of driving a generalised engine to do much the same.
You have 1 of 2 options: 1. Compose a list of chars that CAN be in the string, then loop over the string checking to make sure each character IS in the list. 2. Compose a list of chars that CANNOT be in the string, then loop over the string checking to make sure each character IS NOT in the list.
Choose whatever option is quicker to compose the list.